﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="XRM.cs" company="SMART business">
//   SMART business.
// </copyright>
// <summary>
//   The xrm interface.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Web;
using System.Xml.Linq;
using McTools.Xrm.Connection;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Metadata;
using Microsoft.Xrm.Sdk.Query;
using smartsaas;
using UsersSettingsTool.Additional_Classes.Classes;
using UsersSettingsTool.Models.Interfaces;
using UsersSettingsTool.Options;

namespace UsersSettingsTool.Models.Classes
{
    /// <summary>
    /// The main model class.
    /// </summary>
    public class Xrm : IXrm
    {
        private bool _isUnauthorized = true;

        /// <summary>
        /// The service.
        /// </summary>
        private IOrganizationService _service;

        /// <summary>
        /// The lock object.
        /// </summary>
        private readonly object _lockObject;

        /// <summary>
        /// The locale id.
        /// </summary>
        private int _localeId;

        /// <summary>
        /// Gets or sets the all entities.
        /// </summary>
        private RetrieveAllEntitiesResponse AllEntities { get; set; }

        /// <summary>
        /// The connection detail.
        /// </summary>
        private ConnectionDetail _connectionDetail;

        /// <summary>
        /// The site map xml.
        /// </summary>
        private XElement _siteMapXml;

        /// <summary>
        /// Gets or sets the panes.
        /// </summary>
        private List<Pane> _panes;

        private List<TimeZones> _timeZones;

        /// <summary>
        /// Gets or sets the tabs.
        /// </summary>
        private List<Tab> _tabs;

        private List<RecordPerPage> _recordsPerPage;

        /// <summary>
        /// The system users.
        /// </summary>
        private List<CrmUser> _systemUsers;

        public Xrm()
        {
            _lockObject = new Object();
        }

        /// <summary>
        /// The connection status.
        /// </summary>
        /// <param name="e">
        /// The e.
        /// </param>
        public void ConnectionStatus(EventArgs e)
        {
            if (e.GetType() == typeof(ConnectionFailedEventArgs))
            {
                _service = null;
            }
            else if (e.GetType() == typeof(ConnectionSucceedEventArgs))
            {
                _isUnauthorized = true;

                _service = ((ConnectionSucceedEventArgs)e).OrganizationService;
                _connectionDetail = ((ConnectionSucceedEventArgs)e).ConnectionDetail;

                AllEntities = null;
                _siteMapXml = null;
                _panes = null;
                _tabs = null;
                _systemUsers = null;
                _timeZones = null;

                try
                {
                    RetrieveAllEntities();
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.Message, ex);
                }
            }
        }

        public List<CrmUser> GetSystemUsers()
        {
            if (_service == null)
            {
                throw new NullReferenceException("No connection.");
            }

            var query = new QueryExpression("systemuser") { ColumnSet = new ColumnSet("systemuserid", "fullname", "businessunitid", "isdisabled") };

            query.LinkEntities.Add(new LinkEntity
                {
                    LinkFromEntityName = "systemuser",
                    LinkToEntityName = "usersettings",
                    LinkFromAttributeName = "systemuserid",
                    LinkToAttributeName = "systemuserid",
                    JoinOperator = JoinOperator.Inner,
                    Columns = new ColumnSet(
                         "homepagearea",
                         "homepagesubarea",
                         "paginglimit",
                         "timezonecode",
                         "defaultcalendarview",
                         "workdaystarttime",
                         "workdaystoptime",
                         "issendasallowed",
                         "incomingemailfilteringmethod",
                         "autocreatecontactonpromote",
                         "advancedfindstartupmode",
                         "getstartedpanecontentenabled",
                         "reportscripterrors",
                         "transactioncurrencyid",
                         "useimagestrips",
                         "isdefaultcountrycodecheckenabled",
                         "defaultcountrycode",
                         "helplanguageid",
                         "uilanguageid"),
                    EntityAlias = "settings"
                });

            var systemUsersList = _service.RetrieveMultiple(query).Entities;

            _systemUsers = new List<CrmUser>();

            foreach (var user in systemUsersList)
            {
                var id = user.Id;
                var fullName = Helper.GetValue<string>("fullname", user);
                var businessUnit = Helper.GetValue<EntityReference>("businessunitid", user).Name;

                var pane = GetUserPane(user.GetAttributeValue<AliasedValue>("settings.homepagearea"));
                var tab = GetUserTab(user.GetAttributeValue<AliasedValue>("settings.homepagesubarea"));

                var recordsPerPage = GetRecordPerPage(user.GetAttributeValue<AliasedValue>("settings.paginglimit"));
                var timeZone = GetUserTimeZone(user.GetAttributeValue<AliasedValue>("settings.timezonecode"));
                var advFindMode = (int)user.GetAttributeValue<AliasedValue>("settings.advancedfindstartupmode").Value;

                var currency = new Currency();

                var transactioncurrencyid = Helper.GetAliasedValue<AliasedValue>("settings.transactioncurrencyid", user);
                if (transactioncurrencyid != null)
                {
                    var value = (EntityReference)transactioncurrencyid.Value;
                    currency = new Currency(value.Name, value.Id);
                }

                var enableHighContrast = !(bool)user.GetAttributeValue<AliasedValue>("settings.useimagestrips").Value;
                var enableCountryRegionCodePrefixing = (bool)user.GetAttributeValue<AliasedValue>("settings.isdefaultcountrycodecheckenabled").Value;
                var countryCode = user.GetAttributeValue<AliasedValue>("settings.defaultcountrycode") != null ? user.GetAttributeValue<AliasedValue>("settings.defaultcountrycode").Value.ToString() : string.Empty;
                var calendarView = (int)user.GetAttributeValue<AliasedValue>("settings.defaultcalendarview").Value;
                var workDayStartTime = user.GetAttributeValue<AliasedValue>("settings.workdaystarttime").Value.ToString();
                var workDayStopTime = user.GetAttributeValue<AliasedValue>("settings.workdaystoptime").Value.ToString();
                var incomingEmailFilteringMethod = ((OptionSetValue)user.GetAttributeValue<AliasedValue>("settings.incomingemailfilteringmethod").Value).Value;
                var isSendAsAllowed = (bool)user.GetAttributeValue<AliasedValue>("settings.issendasallowed").Value;
                var autoCreateContactOnPromote = (int)user.GetAttributeValue<AliasedValue>("settings.autocreatecontactonpromote").Value;
                var reportScriptErrors = ((OptionSetValue)user.GetAttributeValue<AliasedValue>("settings.reportscripterrors").Value).Value;
                var helpLanguage = (int)user.GetAttributeValue<AliasedValue>("settings.helplanguageid").Value;
                var uiLanguage = (int)user.GetAttributeValue<AliasedValue>("settings.uilanguageid").Value;
                var isDisabled = user.GetAttributeValue<bool>("isdisabled");

                var crmUser = new CrmUser
                                  {
                                      Id = id,
                                      FullName = fullName,
                                      BusinessUnit = businessUnit,
                                      Pane = pane,
                                      Tab = tab,
                                      RecordsPerPage = recordsPerPage,
                                      TimeZone = timeZone,
                                      AdvFindMode = advFindMode,
                                      Currency = currency,
                                      IsEnableHighContrast = enableHighContrast,
                                      IsEnableCountryRegionCodePrefixing = enableCountryRegionCodePrefixing,
                                      CountryCode = countryCode,
                                      CalendarView = calendarView,
                                      WorkDayStartTime = workDayStartTime,
                                      WorkDayStopTime = workDayStopTime,
                                      IncomingEmailFilteringMethod = incomingEmailFilteringMethod,
                                      IsSendAsAllowed = isSendAsAllowed,
                                      AutoCreateContactOnPromote = autoCreateContactOnPromote,
                                      ReportScriptErrors = reportScriptErrors,
                                      HelpLanguage = helpLanguage,
                                      UiLanguage = uiLanguage,
                                      IsDisabled = isDisabled
                                  };

                _systemUsers.Add(crmUser);
            }

            return _systemUsers;
        }

        private TimeZones GetUserTimeZone(AliasedValue value)
        {
            if (value != null)
            {
                var name = string.Empty;

                foreach (var zone in _timeZones)
                {
                    if (zone.Value == (int)value.Value)
                    {
                        name = zone.Text;
                        break;
                    }
                }

                return new TimeZones(name, (int)value.Value);
            }

            return new TimeZones();
        }

        private RecordPerPage GetRecordPerPage(AliasedValue value)
        {
            if (value != null)
            {
                var name = string.Empty;

                foreach (var num in _recordsPerPage.Where(num => num.Value.Equals(value.Value)))
                {
                    name = num.Text;
                    break;
                }

                return new RecordPerPage(name, (int)value.Value);
            }

            return new RecordPerPage();
        }

        private Tab GetUserTab(AliasedValue value)
        {
            if (value != null)
            {
                var name = string.Empty;

                foreach (var tab in _tabs.Where(tab => tab.Value.Equals(value.Value)))
                {
                    name = tab.Text;
                    break;
                }

                return new Tab(name, value.Value.ToString());
            }

            return new Tab();
        }

        private Pane GetUserPane(AliasedValue value)
        {
            if (value != null)
            {
                foreach (var pane in _panes.Where(pane => pane.Value.Equals(value.Value)))
                {
                    return new Pane(pane.Text, value.Value.ToString());
                }

                return new Pane("<Default>", "<Default>");
            }

            return new Pane();
        }

        /// <summary>
        /// The retrieve current users settings.
        /// </summary>
        private void RetrieveCurrentUsersSettings()
        {
            var currentUserSettings =
                _service.RetrieveMultiple(new QueryExpression("usersettings")
                        {
                            ColumnSet = new ColumnSet("localeid", "timezonecode"),
                            Criteria = new FilterExpression { Conditions = { new ConditionExpression("systemuserid", ConditionOperator.EqualUserId) } }
                        }).Entities[0];

            _localeId = (int)currentUserSettings["localeid"];
        }

        public string GetOrganizationUrl()
        {
            if (_service == null)
            {
                throw new NullReferenceException("No connection.");
            }

            return _connectionDetail.OrganizationServiceUrl.Replace("/XRMServices/2011/Organization.svc", string.Empty);
        }

        public List<TimeZones> GetTimeZones()
        {
            if (_localeId == 0)
            {
                RetrieveCurrentUsersSettings();
            }

            var request = new GetAllTimeZonesWithDisplayNameRequest { LocaleId = _localeId };

            var entityCollection = (GetAllTimeZonesWithDisplayNameResponse)_service.Execute(request);

            if (entityCollection != null)
            {
                var list =
                    new List<TimeZones>(
                        entityCollection.EntityCollection.Entities.Select(
                            entity => new TimeZones(
                                                        entity["userinterfacename"].ToString(),
                                                        (int)entity["timezonecode"])
                                                    ).OrderBy(x => x.Text));

                list.Insert(0, new TimeZones("Default"));

                _timeZones = list;
                return list;
            }

            return new List<TimeZones>();
        }

        public List<Pane> GetPanes()
        {
            var panes = new List<Pane> { new Pane { Text = "<Default>", Value = "<Default>" } };

            if (_siteMapXml == null)
            {
                var request = new QueryExpression("sitemap") { ColumnSet = new ColumnSet("sitemapxml") };
                var sitemap = _service.RetrieveMultiple(request).Entities.FirstOrDefault();

                if (sitemap != null)
                {
                    _siteMapXml = XElement.Parse((string)sitemap["sitemapxml"]);
                }
                else
                {
                    _panes = panes;
                    return panes;
                }
            }

            var areas = _siteMapXml.Descendants("Area").Where(x => x.Attribute("ResourceId") != null);

            foreach (var area in areas)
            {
                var pane = new Pane
                {
                    Text = area.Attribute("ResourceId").Value.Replace("Area_", string.Empty).ToString(CultureInfo.InvariantCulture),
                    Value = area.Attribute("Id").Value.ToString(CultureInfo.InvariantCulture)
                };

                panes.Add(pane);
            }

            _panes = panes;
            return panes;
        }

        public List<Tab> GetTabs()
        {
            var tabs = new List<Tab> { new Tab("<Default>", string.Empty, string.Empty) };

            if (_siteMapXml == null)
            {
                var request = new QueryExpression("sitemap") { ColumnSet = new ColumnSet("sitemapxml") };
                var sitemap = _service.RetrieveMultiple(request).Entities.FirstOrDefault();

                if (sitemap != null)
                {
                    _siteMapXml = XElement.Parse((string)sitemap["sitemapxml"]);
                }
                else
                {
                    _tabs = tabs;
                    return tabs;
                }
            }

            tabs.AddRange(
                from area in _siteMapXml.Descendants("Area")
                from subArea in area.Descendants("SubArea")
                let text = subArea.Attribute("Entity") != null
                            ? GetEntityDisplayName(subArea.Attribute("Entity").Value)
                            : subArea.Attribute("ResourceId") != null
                                ? subArea.Attribute("ResourceId").Value
                                : string.Empty
                let value = subArea.Attribute("Id").Value
                select new Tab(text, value, area.Attribute("Id").Value));

            _tabs = tabs;

            return tabs;
        }

        /// <summary>
        /// The retrieve all entities.
        /// </summary>
        private void RetrieveAllEntities()
        {
            lock (_lockObject)
            {
                if (AllEntities == null && _isUnauthorized)
                {
                    var request = new RetrieveAllEntitiesRequest
                                      {
                                          EntityFilters = EntityFilters.Entity,
                                          RetrieveAsIfPublished = true
                                      };

                    try
                    {
                        AllEntities = (RetrieveAllEntitiesResponse)_service.Execute(request);
                    }
                    catch (Exception ex)
                    {
                        if (ex.Message.Contains("access") || ex.Message.Contains("GetMaxPrivilege"))
                        {
                            _isUnauthorized = false;
                            throw new Exception("Insufficient user rights. See Log file for error description.", ex);
                        }

                        throw new Exception(ex.Message, ex.InnerException);
                    }
                }
            }
        }

        private string GetEntityDisplayName(string name)
        {
            if (AllEntities == null)
            {
                RetrieveAllEntities();
            }

            if (AllEntities != null)
                foreach (var metadata in AllEntities.EntityMetadata.Where(metadata => metadata.LogicalName.Equals(name)))
                {
                    return metadata.DisplayName.UserLocalizedLabel.Label;
                }

            return name;
        }

        public List<Currency> GetCurrencies()
        {
            var query = new QueryExpression("transactioncurrency") { ColumnSet = new ColumnSet("currencyname") };
            var result = _service.RetrieveMultiple(query).Entities;

            var list = new List<Currency>(
                result.Select(
                    entity =>
                    new Currency
                        {
                            Text = entity["currencyname"].ToString(),
                            Value = (Guid)entity["transactioncurrencyid"]
                        }).ToList());

            list.Insert(0, new Currency { Text = "Empty", Value = Guid.Empty });

            return list;
        }

        public Guid GetCurrentUserId()
        {
            if (_service == null)
            {
                throw new NullReferenceException("No connection.");
            }

            var request = new WhoAmIRequest();
            var response = (WhoAmIResponse)_service.Execute(request);

            return response != null ? response.UserId : new Guid();
        }

        public List<CalendarList> GetCalenderList()
        {
            var calendarList = new List<CalendarList>
                                   {
                                       new CalendarList("Default", -1 ), 
                                       new CalendarList("Day", 0 ),
                                       new CalendarList("Week", 1 ),  
                                       new CalendarList("Month", 2 )
                                   };
            return calendarList;
        }

        public List<object> GetTimesList()
        {
            var times = new List<object>
                            {
                                new { Text = "Default", Value = "00:00" }, 
                                new { Text = "12:00 AM", Value = "00:00" }, 
                                new { Text = "12:30 AM", Value = "00:30" }, 
                                new { Text = "01:00 AM", Value = "01:00" }, 
                                new { Text = "01:30 AM", Value = "01:30" }, 
                                new { Text = "02:00 AM", Value = "02:00" }, 
                                new { Text = "02:30 AM", Value = "02:30" }, 
                                new { Text = "03:00 AM", Value = "03:00" }, 
                                new { Text = "03:30 AM", Value = "03:30" }, 
                                new { Text = "04:00 AM", Value = "04:00" }, 
                                new { Text = "04:30 AM", Value = "04:30" }, 
                                new { Text = "05:00 AM", Value = "05:00" }, 
                                new { Text = "05:30 AM", Value = "05:30" }, 
                                new { Text = "06:00 AM", Value = "06:00" }, 
                                new { Text = "06:30 AM", Value = "06:30" }, 
                                new { Text = "07:00 AM", Value = "07:00" }, 
                                new { Text = "07:30 AM", Value = "07:30" }, 
                                new { Text = "08:00 AM", Value = "08:00" }, 
                                new { Text = "08:30 AM", Value = "08:30" }, 
                                new { Text = "09:00 AM", Value = "09:00" }, 
                                new { Text = "09:30 AM", Value = "09:30" }, 
                                new { Text = "10:00 AM", Value = "10:00" }, 
                                new { Text = "10:30 AM", Value = "10:30" }, 
                                new { Text = "11:00 AM", Value = "11:00" }, 
                                new { Text = "11:30 AM", Value = "11:30" }, 
                                new { Text = "12:00 PM", Value = "12:00" }, 
                                new { Text = "12:30 PM", Value = "12:30" }, 
                                new { Text = "01:00 PM", Value = "13:00" }, 
                                new { Text = "01:30 PM", Value = "13:30" }, 
                                new { Text = "02:00 PM", Value = "14:00" }, 
                                new { Text = "02:30 PM", Value = "14:30" }, 
                                new { Text = "03:00 PM", Value = "15:00" }, 
                                new { Text = "03:30 PM", Value = "15:30" }, 
                                new { Text = "04:00 PM", Value = "16:00" }, 
                                new { Text = "04:30 PM", Value = "16:30" }, 
                                new { Text = "05:00 PM", Value = "17:00" }, 
                                new { Text = "05:30 PM", Value = "17:30" }, 
                                new { Text = "06:00 PM", Value = "18:00" }, 
                                new { Text = "06:30 PM", Value = "18:30" }, 
                                new { Text = "07:00 PM", Value = "19:00" }, 
                                new { Text = "07:30 PM", Value = "19:30" }, 
                                new { Text = "08:00 PM", Value = "20:00" }, 
                                new { Text = "08:30 PM", Value = "20:30" }, 
                                new { Text = "09:00 PM", Value = "21:00" }, 
                                new { Text = "09:30 PM", Value = "21:30" }, 
                                new { Text = "10:00 PM", Value = "22:00" }, 
                                new { Text = "10:30 PM", Value = "22:30" }, 
                                new { Text = "11:00 PM", Value = "23:00" }, 
                                new { Text = "11:30 PM", Value = "23:30" }
                            };
            return times;
        }

        public List<object> GetInstalledLanguages()
        {
            var request = new RetrieveAvailableLanguagesRequest();
            var response = (RetrieveAvailableLanguagesResponse)_service.Execute(request);

            var result = new List<object> { new { Text = "Default", Value = -1 } };

            foreach (var languagePack in response.LocaleIds)
            {
                result.Add(
                    new
                        {
                            Text = LanguageLcid.Languages[languagePack.ToString(CultureInfo.InvariantCulture)],
                            Value = languagePack
                        });
            }

            return result;
        }

        public string GetBaseLanguage()
        {
            return string.Empty;
        }

        public CrmUser GetUser(Guid id)
        {
            return _systemUsers.FirstOrDefault(systemUser => systemUser.Id.Equals(id));
        }

        public List<RecordPerPage> GetRecordsPerPage()
        {
            _recordsPerPage = new List<RecordPerPage>
                       {
                           new RecordPerPage("Default",  50), 
                           new RecordPerPage("25",       25), 
                           new RecordPerPage("50",       50),  
                           new RecordPerPage("75",       75),  
                           new RecordPerPage( "100",     100),  
                           new RecordPerPage("250",      250)
                       };

            return _recordsPerPage;
        }

        public List<object> GetTrackValues()
        {
            return new List<object>
                       {
                           new { Text = "Default",                                                  Value = 0 }, 
                           new { Text = "All email messages",                                       Value = 0 }, 
                           new { Text = "Email messages in response to CRM email",                  Value = 1 }, 
                           new { Text = "Email messages from CRM Leads, Contacts and Accounts",     Value = 2 }, 
                           new { Text = "Email messages from CRM records that are email enabled",   Value = 3 }
                       };
        }

        public List<object> GetCreateFromEmailOptions()
        {
            return new List<object>
                       {
                           new { Text = "Default",  Value = 0 }, 
                           new { Text = "Contacts", Value = 1 }, 
                           new { Text = "Leads",    Value = 2 }
                       };
        }

        public EntityReference GetMailBox(Guid userId)
        {
            var query = new QueryExpression(Mailbox.EntityLogicalName) { ColumnSet = new ColumnSet(false) };
            query.Criteria.AddCondition("regardingobjectid", ConditionOperator.Equal, userId);

            var entity = _service.RetrieveMultiple(query).Entities.FirstOrDefault();
            if (entity != null)
            {
                return entity.ToEntityReference();
            }

            return null;
        }

        public List<Format> GetFormats()
        {
            // var s = GetDefaultsForAllLocales();
            return new List<Format>
                       {
                           new Format("0", "Default"), 
                           new Format("1078", "Afrikaans (South Africa)"),
                           new Format("1052", "Albanian (Albania)"),
                           new Format("1156", "Alsatian (France)"),
                           new Format("1118", "Amharic (Ethiopia)"),
                           new Format("5121", "Arabic (Algeria)"),
                           new Format("15361", "Arabic (Bahrain)"),
                           new Format("3073", "Arabic (Egypt)"),
                           new Format("2049", "Arabic (Iraq)"),
                           new Format("11265", "Arabic (Jordan)"),
                           new Format("13313", "Arabic (Kuwait)"),
                           new Format("12289", "Arabic (Lebanon)"),
                           new Format("4097", "Arabic (Libya)"),
                           new Format("6145", "Arabic (Morocco)"),
                           new Format("8193", "Arabic (Oman)"),
                           new Format("16385", "Arabic (Qatar)"),
                           new Format("1025", "Arabic (Saudi Arabia)"),
                           new Format("10241", "Arabic (Syria)"),
                           new Format("7169", "Arabic (Tunisia)"),
                           new Format("14337", "Arabic (U.A.E.)"),
                           new Format("9217", "Arabic (Yemen)"),
                           new Format("1067", "Armenian (Armenia)"),
                           new Format("1101", "Assamese (India)"),
                           new Format("2092", "Azerbaijani (Cyrillic, Azerbaijan)"),
                           new Format("1068", "Azerbaijani (Latin, Azerbaijan)"),
                           new Format("2117", "Bangla (Bangladesh)"),
                           new Format("1093", "Bangla (India)"),
                           new Format("1133", "Bashkir (Russia)"),
                           new Format("1069", "Basque (Basque)"),
                           new Format("1059", "Belarusian (Belarus)"),
                           new Format("8218", "Bosnian (Cyrillic, Bosnia and Herzegovina)"),
                           new Format("5146", "Bosnian (Latin, Bosnia and Herzegovina)"),
                           new Format("1150", "Breton (France)"),
                           new Format("1026", "Bulgarian (Bulgaria)"),
                           new Format("1027", "Catalan (Catalan)"),
                           new Format("3076", "Chinese (Hong Kong S.A.R.)"),
                           new Format("5124", "Chinese (Macao S.A.R.)"),
                           new Format("2052", "Chinese (People's Republic of China)"),
                           new Format("4100", "Chinese (Singapore)"),
                           new Format("1028", "Chinese (Taiwan)"),
                           new Format("1155", "Corsican (France)"),
                           new Format("4122", "Croatian (Bosnia and Herzegovina)"),
                           new Format("1050", "Croatian (Croatia)"),
                           new Format("1029", "Czech (Czech Republic)"),
                           new Format("1030", "Danish (Denmark)"),
                           new Format("1164", "Dari (Afghanistan)"),
                           new Format("1125", "Divehi (Maldives)"),
                           new Format("2067", "Dutch (Belgium)"),
                           new Format("1043", "Dutch (Netherlands)"),
                           new Format("3081", "English (Australia)"),
                           new Format("10249", "English (Belize)"),
                           new Format("4105", "English (Canada)"),
                           new Format("9225", "English (Caribbean)"),
                           new Format("16393", "English (India)"),
                           new Format("6153", "English (Ireland)"),
                           new Format("8201", "English (Jamaica)"),
                           new Format("17417", "English (Malaysia)"),
                           new Format("5129", "English (New Zealand)"),
                           new Format("13321", "English (Republic of the Philippines)"),
                           new Format("18441", "English (Singapore)"),
                           new Format("7177", "English (South Africa)"),
                           new Format("11273", "English (Trinidad and Tobago)"),
                           new Format("2057", "English (United Kingdom)"),
                           new Format("1033", "English (United States)"),
                           new Format("12297", "English (Zimbabwe)"),
                           new Format("1061", "Estonian (Estonia)"),
                           new Format("1080", "Faroese (Faroe Islands)"),
                           new Format("1124", "Filipino (Philippines)"),
                           new Format("1035", "Finnish (Finland)"),
                           new Format("2060", "French (Belgium)"),
                           new Format("3084", "French (Canada)"),
                           new Format("1036", "French (France)"),
                           new Format("5132", "French (Luxembourg)"),
                           new Format("6156", "French (Principality of Monaco)"),
                           new Format("4108", "French (Switzerland)"),
                           new Format("1122", "Frisian (Netherlands)"),
                           new Format("1110", "Galician (Galician)"),
                           new Format("1079", "Georgian (Georgia)"),
                           new Format("3079", "German (Austria)"),
                           new Format("1031", "German (Germany)"),
                           new Format("5127", "German (Liechtenstein)"),
                           new Format("4103", "German (Luxembourg)"),
                           new Format("2055", "German (Switzerland)"),
                           new Format("1032", "Greek (Greece)"),
                           new Format("1135", "Greenlandic (Greenland)"),
                           new Format("1095", "Gujarati (India)"),
                           new Format("1128", "Hausa (Latin) (Nigeria)"),
                           new Format("1037", "Hebrew (Israel)"),
                           new Format("1081", "Hindi (India)"),
                           new Format("1038", "Hungarian (Hungary)"),
                           new Format("1039", "Icelandic (Iceland)"),
                           new Format("1136", "Igbo (Nigeria)"),
                           new Format("1057", "Indonesian (Indonesia)"),
                           new Format("1117", "Inuktitut (Canada)"),
                           new Format("2141", "Inuktitut (Latin, Canada)"),
                           new Format("2108", "Irish (Ireland)"),
                           new Format("1040", "Italian (Italy)"),
                           new Format("2064", "Italian (Switzerland)"),
                           new Format("1041", "Japanese (Japan)"),
                           new Format("1158", "K'iche (Guatemala)"),
                           new Format("1099", "Kannada (India)"),
                           new Format("1087", "Kazakh (Kazakhstan)"),
                           new Format("1107", "Khmer (Cambodia)"),
                           new Format("1159", "Kinyarwanda (Rwanda)"),
                           new Format("1089", "Kiswahili (Kenya)"),
                           new Format("1111", "Konkani (India)"),
                           new Format("1042", "Korean (Korea)"),
                           new Format("1088", "Kyrgyz (Kyrgyzstan)"),
                           new Format("1108", "Lao (Lao P.D.R.)"),
                           new Format("1062", "Latvian (Latvia)"),
                           new Format("1063", "Lithuanian (Lithuania)"),
                           new Format("2094", "Lower Sorbian (Germany)"),
                           new Format("1134", "Luxembourgish (Luxembourg)"),
                           new Format("1071", "Macedonian (Former Yugoslav Republic of Macedonia)"),
                           new Format("2110", "Malay (Brunei Darussalam)"),
                           new Format("1086", "Malay (Malaysia)"),
                           new Format("1100", "Malayalam (India)"),
                           new Format("1082", "Maltese"),
                           new Format("1153", "Maori"),
                           new Format("1146", "Mapudungun (Chile)"),
                           new Format("1102", "Marathi (India)"),
                           new Format("1148", "Mohawk (Mohawk)"),
                           new Format("1104", "Mongolian (Cyrillic, Mongolia)"),
                           new Format("2128", "Mongolian (Traditional Mongolian) (People's Republic of China)"),
                           new Format("1121", "Nepali (Nepal)"),
                           new Format("1044", "Norwegian, Bokmål (Norway)"),
                           new Format("2068", "Norwegian, Nynorsk (Norway)"),
                           new Format("1154", "Occitan (France)"),
                           new Format("1096", "Odia (India)"),
                           new Format("1123", "Pashto (Afghanistan)"),
                           new Format("1065", "Persian (Iran)"),
                           new Format("1045", "Polish (Poland)"),
                           new Format("1046", "Portuguese (Brazil)"),
                           new Format("2070", "Portuguese (Portugal)"),
                           new Format("1094", "Punjabi (India)"),
                           new Format("1131", "Quechua (Bolivia)"),
                           new Format("2155", "Quechua (Ecuador)"),
                           new Format("3179", "Quechua (Peru)"),
                           new Format("1048", "Romanian (Romania)"),
                           new Format("1047", "Romansh (Switzerland)"),
                           new Format("1049", "Russian (Russia)"),
                           new Format("9275", "Sami, Inari (Finland)"),
                           new Format("4155", "Sami, Lule (Norway)"),
                           new Format("5179", "Sami, Lule (Sweden)"),
                           new Format("3131", "Sami, Northern (Finland)"),
                           new Format("1083", "Sami, Northern (Norway)"),
                           new Format("2107", "Sami, Northern (Sweden)"),
                           new Format("8251", "Sami, Skolt (Finland)"),
                           new Format("6203", "Sami, Southern (Norway)"),
                           new Format("7227", "Sami, Southern (Sweden)"),
                           new Format("1103", "Sanskrit (India)"),
                           new Format("1169", "Scottish Gaelic (United Kingdom)"),
                           new Format("7194", "Serbian (Cyrillic, Bosnia and Herzegovina)"),
                           new Format("12314", "Serbian (Cyrillic, Montenegro)"),
                           new Format("3098", "Serbian (Cyrillic, Serbia)"),
                           new Format("10266", "Serbian (Cyrillic, Serbia) (sr-Cyrl-RS) (10266)"),
                           new Format("6170", "Serbian (Latin, Bosnia and Herzegovina)"),
                           new Format("11290", "Serbian (Latin, Montenegro)"),
                           new Format("2074", "Serbian (Latin, Serbia)"),
                           new Format("9242", "Serbian (Latin, Serbia) (sr-Latn-RS) (9242)"),
                           new Format("1132", "Sesotho sa Leboa (South Africa)"),
                           new Format("1074", "Setswana (South Africa)"),
                           new Format("1115", "Sinhala (Sri Lanka)"),
                           new Format("1051", "Slovak (Slovakia)"),
                           new Format("1060", "Slovenian (Slovenia)"),
                           new Format("11274", "Spanish (Argentina)"),
                           new Format("16394", "Spanish (Bolivia)"),
                           new Format("13322", "Spanish (Chile)"),
                           new Format("9226", "Spanish (Colombia)"),
                           new Format("5130", "Spanish (Costa Rica)"),
                           new Format("7178", "Spanish (Dominican Republic)"),
                           new Format("12298", "Spanish (Ecuador)"),
                           new Format("17418", "Spanish (El Salvador)"),
                           new Format("4106", "Spanish (Guatemala)"),
                           new Format("18442", "Spanish (Honduras)"),
                           new Format("2058", "Spanish (Mexico)"),
                           new Format("19466", "Spanish (Nicaragua)"),
                           new Format("6154", "Spanish (Panama)"),
                           new Format("15370", "Spanish (Paraguay)"),
                           new Format("10250", "Spanish (Peru)"),
                           new Format("20490", "Spanish (Puerto Rico)"),
                           new Format("3082", "Spanish (Spain)"),
                           new Format("21514", "Spanish (United States)"),
                           new Format("14346", "Spanish (Uruguay)"),
                           new Format("8202", "Spanish (Venezuela)"),
                           new Format("2077", "Swedish (Finland)"),
                           new Format("1053", "Swedish (Sweden)"),
                           new Format("1114", "Syriac (Syria)"),
                           new Format("1064", "Tajik (Cyrillic) (Tajikistan)"),
                           new Format("2143", "Tamazight (Latin) (Algeria)"),
                           new Format("1097", "Tamil (India)"),
                           new Format("1092", "Tatar (Russia)"),
                           new Format("1098", "Telugu (India)"),
                           new Format("1054", "Thai (Thailand)"),
                           new Format("1105", "Tibetan (People's Republic of China)"),
                           new Format("1055", "Turkish (Turkey)"),
                           new Format("1090", "Turkmen (Turkmenistan)"),
                           new Format("1152", "Uighur (People's Republic of China)"),
                           new Format("1058", "Ukrainian (Ukraine)"),
                           new Format("1070", "Upper Sorbian (Germany)"),
                           new Format("1056", "Urdu (Islamic Republic of Pakistan)"),
                           new Format("2115", "Uzbek (Cyrillic, Uzbekistan)"),
                           new Format("1091", "Uzbek (Latin, Uzbekistan)"),
                           new Format("1066", "Vietnamese (Vietnam)"),
                           new Format("1106", "Welsh"),
                           new Format("1160", "Wolof (Senegal)"),
                           new Format("1076", "Xhosa"),
                           new Format("1157", "Yakut (Russia)"),
                           new Format("1144", "Yi (People's Republic of China)"),
                           new Format("1130", "Yoruba (Nigeria)"),
                           new Format("1077", "Zulu"),
                       };
        }

        /// <summary>
        /// The update system user.
        /// </summary>
        /// <param name="user">
        /// The user.
        /// </param>
        public void UpdateSystemUser(CrmUser user)
        {
            if (user != null)
            {
                var userSettings = new UserSettings { Attributes = user.Attributes };

                if (!userSettings.Attributes.Count.Equals(0))
                {
                    userSettings.Id = user.Id;
                    _service.Update(userSettings);
                }
            }
        }
    }

    public static class Extensions
    {
        public static void AddRange<T>(this IList<T> list, params T[] objects)
        {
            foreach (var obj in objects)
            {
                list.Add(obj);
            }
        }
    }
}
